package com.gonsin.ta.logic.node;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.gonsin.ta.logic.enums.NodeTypeEnum;
import com.gonsin.ta.logic.components.BaseNode;
import com.gonsin.ta.logic.components.RunNode;
import com.gonsin.ta.logic.components.SignalNode;
import com.gonsin.ta.logic.components.SwitchNode;
import com.gonsin.ta.logic.parse.condition.context.ChainContext;
import com.gonsin.ta.logic.parse.condition.context.ChainContextImpl;
import com.gonsin.ta.logic.parse.condition.context.ChainContextGroovyProxy;
import com.gonsin.ta.logic.process.SignalCenter;
import com.google.gson.annotations.Expose;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;

import javax.persistence.Transient;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.List;

@Builder
@Slf4j
public class NodeComponentProxy implements Serializable {


    /**
     * 是否可执行
     */
    private boolean access;


    /**
     * 执行完之后是否结束
     */
    private boolean end;

    /**
     * 重试次数
     */
    private int retryCount;

    /**
     * 重试多次还是异常之后。抛出
     */
    private List<Class<? extends Exception>> forExceptions;

    /**
     * 节点执行
     */
    @JsonIgnore
    @Expose(serialize = false, deserialize = false)
    private transient BaseNode instance;

    @JsonIgnore
    @Expose(serialize = false, deserialize = false)
    private transient Method method;

    @JsonIgnore
    @Expose(serialize = false, deserialize = false)
    private transient Node node;

    /**
     * 节点id
     */
    private String nodeId;

    /**
     * spring bean名字
     */
    private String beanName;

    /**
     * 节点类型
     */
    private NodeTypeEnum nodeType;

    /**
     * 信号中心
     */
    private SignalCenter signalCenter;

    /**
     * 是否可执行
     */
    public boolean isAccess() {
        return access;
    }

    /**
     * 是否执行完本次就结束
     */
    public boolean isEnd(){
        return end;
    }

    public int getRetryCount() {
        return retryCount;
    }


    public List<Class<? extends Exception>> getRetryForExceptions(){
        return forExceptions;
    }

    public String getNodeId() {
        return nodeId;
    }

    public NodeTypeEnum getNodeType(){
        return nodeType;
    }


    /**
     * 执行节点方法
     */
    public void execute(ChainContext context) throws Exception{
        if(instance instanceof RunNode){
            ((RunNode) instance).processRun(context);
            return;
        }

        if(instance instanceof SignalNode){
            ((SignalNode) instance).processSignal(context);
            return;
        }

        if(instance instanceof SwitchNode){
            String result = ((SwitchNode) instance).processSwitch(context);
            if(context instanceof ChainContextImpl){
                ((ChainContextImpl) context).setSwitchResult(result);
            } else if(context instanceof ChainContextGroovyProxy){
                ((ChainContextGroovyProxy)context).getContext().setSwitchResult(result);
            }
            return;
        }

    }

    public void setNode(Node node) {
        this.node = node;
    }
}
